unit uSocket;

interface

uses
  Windows, uDZThread, uDZSocketUtils, uDZSocket;

type
  TServerConnection = class(TDzServerConnection)
  protected
    BackwardLink: TServerConnection;
    ForwardLink: TServerConnection;
  public
    procedure Link;
    procedure Unlink;
    function Close: Boolean; override;
  end; 
  
procedure CloseServerConnections;

implementation

var
  ConnListLock: TDzCriticalSection;
  ConnList: TServerConnection;
  
procedure CloseServerConnections;
var
  Socket, ForwardLink: TServerConnection;
begin
  ConnListLock.Acquire;
  try
    Socket := ConnList;
    while Assigned(Socket) do
    begin
      ForwardLink := Socket;
      Socket := Socket.ForwardLink;
      ForwardLink.Close;  
    end;
  finally
    ConnListLock.Release;
  end;
end;
  
{ TServerConnection }

procedure TServerConnection.Link;
begin
  ConnListLock.Acquire;
  try
    if Assigned(ConnList) then ConnList.BackwardLink := Self;
    Self.ForwardLink := ConnList;
    Self.BackwardLink := nil;
    ConnList := Self;
  finally
    ConnListLock.Release;
  end; 
end;

procedure TServerConnection.Unlink;
begin
  ConnListLock.Acquire;
  try
    if Assigned(Self.BackwardLink) then Self.BackwardLink.ForwardLink := Self.ForwardLink;    
    if Assigned(Self.ForwardLink) then Self.ForwardLink.BackwardLink := Self.BackwardLink;
    if ConnList = Self then ConnList := Self.ForwardLink;
  finally
    ConnListLock.Release;
  end; 
end;

function TServerConnection.Close: Boolean;
begin
  Result := inherited Close;
  if Result then
  begin
    Unlink;
    Release;
  end;
end;

initialization
  ConnListLock := TDzCriticalSection.Create(100);

finalization
  ConnListLock.Free;
  
end.
